<?php
/**
 * Created by PhpStorm.
 * User: divya
 * Date: 2018/7/31
 * Time: 下午2:26
 */

namespace app\api\service;


use app\api\model\User as UserM;
use app\lib\enum\ScopeEnum;
use app\lib\exception\TokenExption;
use app\lib\exception\WeChatException;
use think\Exception;

class UserToken extends Token
{
    protected $code;
    protected $wxAppID;
    protected $wxAppSecret;
    protected $wxLoginUrl;

    function __construct($code)
    {
        $this->code = $code;
        $this->wxAppID = config('wx.appid');
        $this->wxAppSecret = config('wx.app_secret');
        $this->wxLoginUrl = sprintf(config('wx.login_url'),
            $this->wxAppID, $this->wxAppSecret, $this->code);
    }

    public function get()
    {
        $result = curl_get($this->wxLoginUrl);
        $wxResult = json_decode($result, true);
        if (empty($wxResult)) {
            throw new Exception('获取session以及openid时异常，微信内部错误');
        } else {
            $loginFail = array_key_exists('errcode', $wxResult);
            if ($loginFail) {
                $this->processLoginError($wxResult);
            } else {
                return $this->grantToken($wxResult);
            }
        }
    }

    private function grantToken($wxResult)
    {
//        拿到openid
//        数据库里查找
//        如果存在，则不处理，如果不存在，则新增一条记录
//        生成令牌，准备缓存数据，写入缓存
//        把令牌返回到客户端
//        $openid = $wxResult
        $openid = $wxResult['openid'];
        $user = UserM::getByopenId($openid);
        if ($user) {
            $uid = $user->id;
        } else {
            $uid = $this->saveNewUser($openid);
        }
        $cacheValue = $this->prepareCachedValue($wxResult,$uid);
        $token = $this->saveToCache($cacheValue);
        return $token;
    }
    private function saveToCache($cachedValue){
        $key =  self::gennerateToken();
        $value = json_encode($cachedValue);
        $expire_in = config('setting.token_expire_in');
        $request = cache($key,$value,$expire_in);
        if (!$request){
            throw new TokenExption([
                'msg'=>'服务器缓存异常',
                'errorCode'=>10005
            ]);
        }
        return $key;
    }
    private function prepareCachedValue($wxResult,$uid){
        $cacheValue = $wxResult;
        $cacheValue['uid'] = $uid;
        $cacheValue['scope'] = ScopeEnum::User;
        return $cacheValue;
    }

    private function saveNewUser($openid)
    {
        $user = UserM::create([
           'openid'=>$openid
        ]);
        return $user->id;
    }

    private function processLoginError($wxResult)
    {
        throw new WeChatException([
            'msg' => $wxResult['errmsg'],
            'errorCode' => $wxResult["errcode"]
        ]);
    }

}